define(["require", "exports", "../mve/modelChildren", "../mve/util", "./index"], function (require, exports, modelChildren_1, util_1, index_1) {
    "use strict";
    exports.__esModule = true;
    exports.QueryWrapper = exports.locationHashBind = exports.locationHashChange = exports.hashToParam = exports.createRouter = exports.queryToString = exports.Router = exports.routerView = void 0;
    /**
     * 创建视图
     * @param me
     * @param router
     * @param createRoutes
     * @param other
     * @returns
     */
    function routerView(me, router, createRoutes, other) {
        other = other || {};
        var routes = {};
        mb.Object.forEach(createRoutes, function (v, k) {
            var fun = v;
            routes[k] = fun(router.parentPath.concat(k));
        });
        var notFoundView = other.notFoundView || default404FactoryRouter(router.parentPath.concat("404"));
        var currentRoute = util_1.mve.arrayModelOf([]);
        function clear() {
            if (currentRoute.size() > 0) {
                currentRoute.remove(0);
            }
        }
        me.WatchAfter(function () {
            return router.param();
        }, function (p) {
            if (p) {
                var _a = p.path, first = _a[0], rest = _a.slice(1), query = p.query;
                var currentR = currentRoute.get(0, true);
                if (first) {
                    //有路径
                    var changeR = routes[first] || notFoundView;
                    //并且能找到路由
                    if (currentR == changeR) {
                        //并未发生改变
                        currentR.param({
                            path: rest,
                            query: query
                        });
                    }
                    else {
                        //发生了改变，替换当前route
                        clear();
                        currentRoute.push(changeR);
                        changeR.param({
                            path: rest,
                            query: query
                        });
                    }
                }
                else {
                    clear();
                }
            }
            else {
                clear();
            }
        });
        return (0, modelChildren_1.modelChildren)(currentRoute, function (me, row, i) {
            return row.render(me);
        });
    }
    exports.routerView = routerView;
    var Router = /** @class */ (function () {
        function Router(parentPath, fun) {
            this.parentPath = parentPath;
            this.fun = fun;
            this.param = util_1.mve.valueOf({ path: [], query: {} });
        }
        Router.prototype.current = function () {
            return this.param().path[0];
        };
        Router.prototype.render = function (me) {
            return this.fun(me, this);
        };
        /**
         * 生成合适的路由
         * @param path
         * @param query
         * @returns
         */
        Router.prototype.href = function (path, query) {
            return this.parentPath.concat(path).join('/') + queryToString(query);
        };
        /**
         * 中能在自己的下游路径漫游
         * @param path
         * @param query
         */
        Router.prototype.go = function (path, query) {
            location.hash = this.href(path, query);
        };
        return Router;
    }());
    exports.Router = Router;
    function queryToString(q) {
        if (q) {
            var vs_1 = [];
            mb.Object.forEach(q, function (v, k) {
                if (v instanceof Array) {
                    for (var _i = 0, v_1 = v; _i < v_1.length; _i++) {
                        var i = v_1[_i];
                        vs_1.push(k + "=" + i);
                    }
                }
                else {
                    vs_1.push(k + "=" + v);
                }
            });
            if (vs_1.length > 0) {
                return '?' + vs_1.join('&');
            }
        }
        return '';
    }
    exports.queryToString = queryToString;
    function createRouter(fun) {
        return function (parentPath) {
            return new Router(parentPath, fun);
        };
    }
    exports.createRouter = createRouter;
    //////////////////////////////////////////////////////
    function hashToParam(hash) {
        var query = {};
        var path = [];
        if (hash) {
            var _a = hash.split("?"), pathStr = _a[0], queryStr = _a[1];
            pathStr.slice(1).split("/").forEach(function (v) {
                if (v) {
                    path.push(v);
                }
            });
            if (queryStr) {
                queryStr.split("&").forEach(function (kv) {
                    var _a = kv.split("="), k = _a[0], v = _a[1];
                    var oldV = query[k];
                    if (oldV) {
                        if (Array.isArray(oldV)) {
                            oldV.push(v);
                        }
                        else {
                            query[k] = [oldV, v];
                        }
                    }
                    else {
                        query[k] = v;
                    }
                });
            }
        }
        if (path.length == 0) {
            path.push("index");
        }
        return { path: path, query: query };
    }
    exports.hashToParam = hashToParam;
    function locationHashChange(route) {
        var hash = location.hash;
        route.param(hashToParam(hash));
    }
    exports.locationHashChange = locationHashChange;
    function locationHashBind(route) {
        window.addEventListener("hashchange", function () {
            locationHashChange(route);
        });
        locationHashChange(route);
    }
    exports.locationHashBind = locationHashBind;
    //////////////////////////////////////////////////////////////
    var default404FactoryRouter = createRouter(function (me, router) {
        return (0, index_1.dom)({
            type: "div",
            style: {
                display: "flex", 'flex-direction': "column", 'align-items': 'center', 'justify-content': 'center'
            },
            children: [
                (0, index_1.dom)({
                    type: "div",
                    text: "404"
                }),
                (0, index_1.dom)({
                    type: "div",
                    text: function () {
                        return router.param().path.join('/');
                    }
                }),
                (0, index_1.dom)({
                    type: "div",
                    text: function () {
                        return JSON.stringify(router.param().query);
                    }
                })
            ]
        });
    });
    var QueryWrapper = /** @class */ (function () {
        function QueryWrapper(value) {
            this.value = value;
        }
        return QueryWrapper;
    }());
    exports.QueryWrapper = QueryWrapper;
});
